
local Connection = import("../Connection.lua");
local Input = import("./Input.lua");
local Value = commonlib.inherit(Input);

Value:Property("Value");               -- 值
Value:Property("Text");

function Value:ctor()
end

function Value:Init(block, opt)
    Value._super.Init(self, block, opt);
    self:SetValue(opt.value or "");
    self.__shadow_connection__ = Connection:new():Init(block, "input_connection");
    self.__input_connection__:SetType("input_connection");
    return self;
end

function Value:Render(painter)
    local leftUnitCount, topUnitCount = self:GetLeftTopUnitCount();
    local widthUnitCount, heightUnitCount = self:GetWidthHeightUnitCount();
   
    if (self.__shadow_connection__:IsConnection()) then
        self:SetBrushColor(0xffffffff);
        self:DrawInputValue(widthUnitCount + 0.8 * 2, heightUnitCount + 0.8 * 2, leftUnitCount - 0.8, topUnitCount - 0.8);
        self:SetBrushColor(self:GetBlock():GetColor());
        self:DrawInputValue(widthUnitCount + 0.4 * 2, heightUnitCount + 0.4 * 2, leftUnitCount - 0.4, topUnitCount - 0.4);
    end

    local inputBlock = self:GetInputBlock();
    if (inputBlock) then return inputBlock:Render(painter) end 

    if (self:IsColorShadowType()) then
        -- Shape:SetBrush(self:GetValue());
        -- Shape:DrawInputValue(painter, self.widthUnitCount, self.heightUnitCount);
    else
        self:SetBrushColor(0xffffffff);
        self:DrawInputValue(widthUnitCount, heightUnitCount, leftUnitCount, topUnitCount);
        if (not self:IsEditing()) then
            self:DrawText(self:GetText(), widthUnitCount, heightUnitCount, leftUnitCount, topUnitCount);
        end
        -- if (self:IsInputType() and self:GetShowText() ~= "") then
        --     painter:SetPen("#cccccc");
        --     painter:DrawText((Const.BlockEdgeWidthUnitCount + TextMarginUnitCount) * UnitSize - 10, (self.height - self:GetSingleLineTextHeight()) / 2, '＂');
        --     painter:DrawText(self.width - (Const.BlockEdgeWidthUnitCount + TextMarginUnitCount) * UnitSize - 2, (self.height - self:GetSingleLineTextHeight()) / 2, '＂');
        -- end
    end 
end

function Value:OnSizeChange()
    local leftUnitCount, topUnitCount = self:GetLeftTopUnitCount();
    local widthUnitCount, heightUnitCount = self:GetWidthHeightUnitCount();
    self.__input_connection__:SetLeftTopUnitCount(leftUnitCount, topUnitCount + heightUnitCount / 2);
end

function Value:UpdateWidthHeightUnitCount()
    local inputBlock = self:GetInputBlock();
    if (inputBlock) then return inputBlock:UpdateWidthHeightUnitCount() end

    local text = self:GetValue();
    local widthUnitCount = self:GetTextWidthUnitCount(text);
    if (widthUnitCount > self.FIELD_MAX_WIDTH_UNIT_COUNT) then
        widthUnitCount = self.FIELD_MAX_WIDTH_UNIT_COUNT;
        text = self:GetTextByWidth(text, widthUnitCount);
    end
    self:SetText(text);
    return widthUnitCount + self.FIELD_INPUT_HEIGHT_UNIT_COUNT, self.FIELD_INPUT_HEIGHT_UNIT_COUNT;
end

function Value:UpdateLeftTopUnitCount()
    local inputBlock = self:GetInputBlock();
    if (not inputBlock) then return end
    local leftUnitCount, topUnitCount = self:GetLeftTopUnitCount();
    inputBlock:SetLeftTopUnitCount(leftUnitCount, topUnitCount);
    inputBlock:UpdateLeftTopUnitCount();
end

function Value:ConnectionBlock(block)
    if (block.__output_connection__ and not block.__output_connection__:IsConnection() and self.__input_connection__:IsMatch(block.__output_connection__)) then
        local inputBlock = self:GetInputBlock();
        if (inputBlock and inputBlock:ConnectionBlock(block)) then return true end
        self:GetBlockly():RemoveBlock(block);
        if (block.__is_shadow_block__) then
            self.__shadow_connection__:Connection(block.__output_connection__);
        else
            local inputConnectionConnection = self.__input_connection__:Disconnection();
            self.__input_connection__:Connection(block.__output_connection__);
            self:GetTopBlock():UpdateLayout();
            self:GetBlockly():AddBlock(inputConnectionConnection and inputConnectionConnection:GetBlock(), true);
        end
        return true;
    end

    return false;
end

function Value:GetMouseUI(x, y)
    if (not Value._super.GetMouseUI(self, x, y)) then return end 
    
    local block = self:GetBlock();
    if (block:IsToolBoxBlock()) then return block end 

    local inputBlock = self:GetInputBlock();
    if (inputBlock) then return inputBlock:GetMouseUI(x, y) end
    return self;
end

function Value:OnClick()
    local isCanEdit = commonlib.if_else(self:GetInputBlock() ~= nil, false, true);
    if (not isCanEdit) then return end 
    self:GetBlockly():GetEditor():Show(self);
end

function Value:SaveToXmlNode(xmlnode)
    xmlnode = Value._super.SaveToXmlNode(self, xmlnode);

    if (self:GetInputBlock()) then return xmlnode end 

    table.insert(xmlnode, {
        name = "value",
        [1] = {
            text = self:GetValue(),
            cdata = true,
        }
    });

    return xmlnode;
end

function Value:LoadFromXmlNode(xmlnode)
    Value._super.LoadFromXmlNode(self, xmlnode);

    for _, subXmlNode in ipairs(xmlnode) do
        if (subXmlNode.name == "value") then
            self:SetValue(subXmlNode[1] and subXmlNode[1].text or "");
        end
    end
end

function Value:GetShadowType()
    local option = self:GetOption();
    return option.shadowType or (option.shadow and option.shadow.type) or "";
end

function Value:IsColorShadowType()
    return self:GetShadowType() == "field_color";
end

function Value:GetFieldEditType()
    local shadowType = self:GetShadowType();
    if (shadowType == "field_dropdown") then return "select" end
    if (shadowType == "field_color") then return "color" end
    return "input";
end

function Value:GetInputFieldValue() 
    if (not self:GetInputBlock()) then return self:GetValue() end
    return self:GetInputBlock():GetAllCode();
end
return Value;